package repository

import (
	"context"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"mts/trans_srv/internal/domain"
	"mts/trans_srv/internal/repository/dao"
)

var ErrRecordNotFound = errors.New("记录未找到")

// LanguageRepository 定义了语言仓库的接口
type LanguageRepository interface {
	FindByLangID(ctx context.Context, langID string) (*domain.Language, error)
	Update(ctx context.Context, language domain.Language) error
	Delete(ctx context.Context, langID string) error
	Create(ctx context.Context, language domain.Language) error
	List(ctx context.Context, page, pageSize int) ([]*domain.Language, error)
	UpdateEnabled(ctx context.Context, language *domain.Language) error
	GetEnabledLanguages(ctx context.Context) ([]*domain.Language, error)
	Count(ctx *gin.Context) (int, error)
}

// LanguageRepositoryImpl 实现了 LanguageRepository 接口
type LanguageRepositoryImpl struct {
	dao dao.LanguageDao
}

func (r LanguageRepositoryImpl) Count(ctx *gin.Context) (int, error) {
	count, err := r.dao.Count(ctx)
	if err != nil {
		return 0, err
	}
	return count, nil
}

// NewLanguageRepository 返回 LanguageRepository 接口的实现
func NewLanguageRepository(dao dao.LanguageDao) LanguageRepository {
	return &LanguageRepositoryImpl{dao: dao}
}

// Create 创建语言
func (r LanguageRepositoryImpl) Create(ctx context.Context, language domain.Language) error {
	entity := r.toEntity(language)
	return r.dao.Insert(ctx, &entity)
}

// FindByLangID 根据语言ID获取语言
func (r LanguageRepositoryImpl) FindByLangID(ctx context.Context, langID string) (*domain.Language, error) {
	lan, err := r.dao.FindByLangId(ctx, langID)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		return nil, err
	}
	return r.entityToDomain(lan), nil
}

// List 返回所有语言的列表
func (r LanguageRepositoryImpl) List(ctx context.Context, page, pageSize int) ([]*domain.Language, error) {
	list, err := r.dao.List(ctx, page, pageSize)
	if err != nil {
		return nil, err
	}
	var languages []*domain.Language
	for _, v := range list {
		languages = append(languages, r.entityToDomain(v))
	}
	return languages, nil
}

// Update 更新语言
func (r LanguageRepositoryImpl) Update(ctx context.Context, language domain.Language) error {
	entity := r.toEntity(language)
	err := r.dao.Update(ctx, &entity)
	if err != nil {
		return err
	}
	return nil
}

// Delete 删除语言
func (r LanguageRepositoryImpl) Delete(ctx context.Context, langID string) error {
	err := r.dao.Delete(ctx, langID)
	if err != nil {
		return err
	}
	return nil
}

// UpdateEnabled 更新语言的启用状态
func (r LanguageRepositoryImpl) UpdateEnabled(ctx context.Context, language *domain.Language) error {
	// 检查 lang_id 是否已经存在且 deleted_at 为 NULL
	existingLanguage, err := r.dao.CheckExist(ctx, language.LangID)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return fmt.Errorf("语言不存在: %s", language.LangID)
		}
		return fmt.Errorf("检查语言失败: %w", err)
	}
	// 更新启用状态
	existingLanguage.Enabled = language.Enabled
	err = r.dao.Save(ctx, existingLanguage)
	if err != nil {
		return err
	}
	return nil
}

// GetEnabledLanguages 返回所有启用的语言
func (r LanguageRepositoryImpl) GetEnabledLanguages(ctx context.Context) ([]*domain.Language, error) {
	languages, err := r.dao.GetEnabledLanguages(ctx)
	if err != nil {
		return nil, err
	}
	var enabledLanguages []*domain.Language
	for _, v := range languages {
		if v.Enabled {
			enabledLanguages = append(enabledLanguages, &domain.Language{LangID: v.LangID, Name: v.Name})
		}
	}
	return enabledLanguages, nil
}

// toEntity 将 domain.Language 转换为 dao.Language
func (r LanguageRepositoryImpl) toEntity(l domain.Language) dao.Language {
	return dao.Language{
		LangID:  l.LangID,
		Name:    l.Name,
		Dsc:     l.Dsc,
		Enabled: l.Enabled,
	}
}

// entityToDomain 将 dao.Language 转换为 domain.Language
func (r LanguageRepositoryImpl) entityToDomain(lan *dao.Language) *domain.Language {
	return &domain.Language{
		LangID:  lan.LangID,
		Name:    lan.Name,
		Dsc:     lan.Dsc,
		Enabled: lan.Enabled,
	}
}
